﻿using System;
using System.Drawing;
using RRRSRoguelike.Entities.Props;
using RRRSRoguelike.Enums;
using RRRSRoguelike.Helpers;
using RRRSRoguelike.Managers;
using RRRSRoguelikeData;

namespace RRRSRoguelike.Entities.Creatures
{
	/// <summary>
	/// Player inherits from creature.
	/// </summary>
	public class Player : Creature
	{
		#region variables
		//easier calls
		private GameManager gameManager = GameManager.Instance;
		//super basic inventory - very game specific should be more dynamic
		private Weapon weaponSlot;
		
		
		/// <summary>
		/// event for weapon changed
		/// </summary>
		public event EventHandler WeaponChanged = delegate{};
		//FIXME: 2 events below need wiring up
//		public event EventHandler WeaponDropped = delegate{};
//		public event EventHandler WeaponGrabbed = delegate{};
		
		//Keeps a list of stats associated with the player.  Again should be more dynamic.  
		//I would prefer an interface.
		/// <summary>
		/// Stats
		/// </summary>
		public Stats Stats;
		
		
		#endregion
		
		#region constructor
		/// <summary>
		/// Initializes player
		/// </summary>
		/// <param name="position"></param>
		/// <param name="tileData"></param>
		public Player(Point position, TileData tileData)
			: base(position, tileData)
		{
		}
		#endregion
		
		#region properties
		
		//The following methods are very specific to the vanilla game.  
		//Thinking about a slot class that is plugable into the creature class.
		
		/// <summary>
		/// Takes a weapon and raises an event.
		/// </summary>
		/// <param name="weapon"></param>
		public void AddWeapon(Weapon weapon)
		{
			weaponSlot = weapon;
			if (WeaponChanged != null)
				WeaponChanged(this, EventArgs.Empty);
		}

		/// <summary>
		/// removes weapon and raises event.
		/// </summary>
		public void RemoveWeapon()
		{
			weaponSlot = null;
			if (WeaponChanged != null)
				WeaponChanged(this, EventArgs.Empty);
		}

		/// <summary>
		/// Checks weapon slot
		/// </summary>
		/// <returns></returns>
		public bool HasWeapon()
		{
			return weaponSlot != null;
		}

		/// <summary>
		/// uses current weapon
		/// </summary>
		public void UseWeapon()
		{
			weaponSlot.Use(this);
		}

		/// <summary>
		/// returns the current weapon slot.
		/// </summary>
		public Weapon WeaponSlot
		{
			get { return weaponSlot; }
		}

		#endregion
		
		#region methods
		/// <summary>
		/// moves player then raises event and returns true if successful.
		/// </summary>
		/// <param name="direction"></param>
		/// <param name="distance"></param>
		/// <returns></returns>
		public Boolean MovePlayer(Direction direction, int distance = 1)
		{
			//check for valid move
			for (int i = distance; i > 0; i--)
			{
				Point newPosition = DungeonLevel.GetNewPosition(Position, direction, i);
				if (gameManager.DungeonLevel.IsOKToMove(newPosition))
				{
					((Floor)gameManager.DungeonLevel.GetTile(Position, Layers.Base)).OnExit(this,EventArgs.Empty);
					Position = newPosition;
					((Floor)gameManager.DungeonLevel.GetTile(Position, Layers.Base)).OnEnter(this,EventArgs.Empty);
					
					OnMove(this);
					
					//early out!!!
					return true;
				}
			}
			return false;
		}


		#endregion
	}
}
